﻿using KZ.Express.ENT;
using KZ.Express.Presenter;
using KZ.Express.Resource;
using KZ.Utilities;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Reflection;
using System.Resources;
using System.Windows.Forms;

namespace KZ.Express
{
    public class FormBase : Form, IViewBase
    {
        #region Private Properties

        protected IPresenterBase _presenter;

        protected DataTable _table;

        protected BindingSource _bds;

        protected DataGridView _dtg;

        protected StatusStrip _sst;
        protected ToolStripStatusLabel _lbl;
        protected ToolStripStatusLabel toolStripStatusLabel2;
        private ToolStripStatusLabel lblValue;
        private ToolStripStatusLabel lblMax;
        protected ToolStripProgressBar _progressBar;

        #endregion Private Properties

        #region Private methods

        private void InitializeComponent()
        {
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormBase));
            this._sst = new System.Windows.Forms.StatusStrip();
            this._lbl = new System.Windows.Forms.ToolStripStatusLabel();
            this.toolStripStatusLabel2 = new System.Windows.Forms.ToolStripStatusLabel();
            this._progressBar = new System.Windows.Forms.ToolStripProgressBar();
            this.lblValue = new System.Windows.Forms.ToolStripStatusLabel();
            this.lblMax = new System.Windows.Forms.ToolStripStatusLabel();
            this._sst.SuspendLayout();
            this.SuspendLayout();
            // 
            // _sst
            // 
            this._sst.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this._lbl,
            this.toolStripStatusLabel2,
            this._progressBar,
            this.lblValue,
            this.lblMax});
            this._sst.Location = new System.Drawing.Point(0, 251);
            this._sst.Name = "_sst";
            this._sst.Size = new System.Drawing.Size(464, 22);
            this._sst.SizingGrip = false;
            this._sst.TabIndex = 0;
            this._sst.Text = "statusStrip1";
            // 
            // _lbl
            // 
            this._lbl.Name = "_lbl";
            this._lbl.Size = new System.Drawing.Size(0, 17);
            // 
            // toolStripStatusLabel2
            // 
            this.toolStripStatusLabel2.Name = "toolStripStatusLabel2";
            this.toolStripStatusLabel2.Size = new System.Drawing.Size(382, 17);
            this.toolStripStatusLabel2.Spring = true;
            // 
            // _progressBar
            // 
            this._progressBar.Name = "_progressBar";
            this._progressBar.Size = new System.Drawing.Size(200, 16);
            this._progressBar.Visible = false;
            // 
            // lblValue
            // 
            this.lblValue.Name = "lblValue";
            this.lblValue.Size = new System.Drawing.Size(33, 17);
            this.lblValue.Text = "Value";
            // 
            // lblMax
            // 
            this.lblMax.Name = "lblMax";
            this.lblMax.Size = new System.Drawing.Size(34, 17);
            this.lblMax.Text = "/ Max";
            // 
            // FormBase
            // 
            this.ClientSize = new System.Drawing.Size(464, 273);
            this.Controls.Add(this._sst);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.Name = "FormBase";
            this._sst.ResumeLayout(false);
            this._sst.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private void InitializeControlBase()
        {
            _bds = new BindingSource();

            this.TopLevel = false;
            this.FormBorderStyle = FormBorderStyle.None;
            this.Font = new Font("Times New Roman", 10);
        }

        private void ViewAll()
        {
            try
            {
                PropertyInfo[] properties = this.GetType().GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    object[] attributes = property.GetCustomAttributes(typeof(SearchAttribute), true);
                    if (attributes.Length > 0)
                        if (property.CanWrite)
                            property.SetValue(this, null);
                }
                _presenter.LoadDataTable();
            }
            catch (BusinessLogicException ex)
            {
                SetMessage(ex.Message, false);
            }
        }

        protected void InitializeDataGrid(DataGridView dtg)
        {
            _dtg = dtg;
            _dtg.AutoGenerateColumns = false;
            _dtg.DataSource = _bds;
        }

        protected void ClearControl()
        {
            foreach (Control item in this.Controls)
            {
                if (item is TextBox) (item as TextBox).Text = String.Empty;
                if (item is ComboBox) (item as ComboBox).SelectedIndex = -1;
            }
        }

        protected virtual void InsertRow()
        {
            DataRow row = _table.NewRow();
            if (_table.Columns.Contains("Number"))
                row["Number"] = _dtg.RowCount + 1;
            _table.Rows.Add(row);
        }

        protected virtual void LoadData()
        {
            try
            {
                _presenter.LoadDataTable();
            }
            catch (BusinessLogicException ex)
            {
                SetMessage(ex.Message, false);
            }
        }

        protected virtual void SetSorting(string orderBy)
        {
            //// set order
            if (orderBy == this.OrderBy)
                this.OrderDirection = this.OrderDirection == "ASC" ? "DESC" : "ASC";
            else
                this.OrderDirection = "ASC";
            this.OrderBy = orderBy;

            //// set sort symbol
            if (this.OrderDirection == "ASC")
                _dtg.Columns["col" + orderBy].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
            else
                _dtg.Columns["col" + orderBy].HeaderCell.SortGlyphDirection = SortOrder.Descending;
        }

        protected virtual void btnViewAll_Click(object sender, EventArgs e)
        {
            ViewAll();
        }

        protected virtual void dtg_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (_dtg.Columns[e.ColumnIndex].SortMode != DataGridViewColumnSortMode.NotSortable)
            {
                string orderBy = Utility.StringParse(_dtg.Columns[e.ColumnIndex].DataPropertyName);
                SetSorting(orderBy);
                LoadData();
            }
        }

        #endregion Private methods

        #region Constructors

        public FormBase()
        {
            InitializeComponent();
            InitializeControlBase();

            lblValue.Text = String.Empty;
            lblMax.Text = String.Empty;
        }

        #endregion Constructors

        #region Public Properties

        public int ObjectID { get; set; }

        public ActionName Action { get; set; }

        public SearchCriteria Search
        {
            get
            {
                SearchCriteria search = new SearchCriteria();

                PropertyInfo[] properties = this.GetType().GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    Attribute attributes = property.GetCustomAttribute(typeof(SearchAttribute), true);
                    if (attributes != null)
                        search.Add(property.Name, property.GetValue(this));
                }

                return search;
            }
        }

        [Search]
        public virtual string OrderBy { get; set; }

        [Search]
        public virtual string OrderDirection { get; set; }

        public int EntityID { get; set; }

        public virtual string DocumentNumber { get; set; }

        public virtual EntityBase Entity { get; set; }

        public virtual DataTable Table
        {
            get { return _table; }
            set
            {
                _table = value;
                if (!_table.Columns.Contains("Number"))
                {
                    DataColumn column = new DataColumn("Number", typeof(int));
                    column.ReadOnly = false;
                    _table.Columns.Add(column);
                }

                Global.GenerateNumber(ref _table);
                _bds.DataSource = null;
                _bds.DataSource = _table;
            }
        }

        #endregion Public Properties

        #region Public Methods

        public virtual int GetSelected()
        {
            if (_dtg.CurrentRow == null)
            {
                SetMessage(KZ.Express.Resource.Message.BLM_ERR_SELECT_ITEM.ToString(), false);
                return 0;
            }
            else
                return Utility.IntParse(_dtg.CurrentRow.Cells[0].Value);
        }

        public virtual void Delete()
        {
            try
            {
                if (Global.ShowMessageConfirm(KZ.Express.Resource.Message.BLM_CFM_DELETE.ToString()) == DialogResult.Yes)
                {
                    if (_dtg != null) { _dtg.EndEdit(); }
                    string content = Global.GetStringFromDataGridView(_dtg, 0);
                    _presenter.Delete(content);
                }
            }
            catch (BusinessLogicException ex)
            {
                SetMessage(ex.Message, false);
            }
        }

        public virtual void Save()
        {
            try
            {
                if (_dtg != null) { _dtg.EndEdit(); }
                _presenter.Save();
            }
            catch (BusinessLogicException ex)
            {
                SetMessage(ex.Message, false);
            }
        }

        public void SetMessage(string message, bool isSuccess)
        {
            ResourceManager resource = new ResourceManager("KZ.Express.KZ.Express.Resource", typeof(KZ_Express_Resource).Assembly);
            string msg = resource.GetString(message);

            _lbl.Text = String.IsNullOrWhiteSpace(msg) ? message : msg;
            if (isSuccess) { _lbl.ForeColor = Color.Blue; }
            else { _lbl.ForeColor = Color.Red; }
        }

        public void ChangeProgressBarVisible(bool isVisible)
        {
            _progressBar.Visible = isVisible;
            lblMax.Visible = isVisible;
            lblValue.Visible = isVisible;
            if (!isVisible)
            {
                _progressBar.Maximum = 100;
                lblValue.Text = String.Empty;
                lblMax.Text = String.Empty;
            }
        }

        public void ChangeProgressBarMaximum(int value)
        {
            _progressBar.Maximum = value;
            lblMax.Text = "/  " + value;
            lblValue.Text = "0";
        }

        public void PerformStepProgressBar(int value)
        {
            if (_progressBar.Value < _progressBar.Maximum)
            {
                _progressBar.Value += value;
                lblValue.Text = _progressBar.Value.ToString();
            }
        }

        public void UpdateValueProgressBar(int value)
        {
            if (_progressBar.Value < _progressBar.Maximum)
            {
                _progressBar.Value = value;
                lblValue.Text = value.ToString();
            }
        }

        #endregion Public Methods
    }
}